home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / disk / misc / ADFlib.lha / Lib / adf_bitm.c next >
C/C++ Source or Header  |  1999-05-09  |  13KB  |  541 lines

  1. /*
  2.  *  ADF Library. (C) 1997-1998 Laurent Clevy
  3.  *
  4.  *  adf_bitm.c
  5.  *
  6.  *  bitmap code
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #include"adf_raw.h"
  13. #include"adf_bitm.h"
  14. #include"adf_err.h"
  15. #include"adf_disk.h"
  16. #include"adf_util.h"
  17. #include"defendian.h"
  18.  
  19. extern unsigned long bitMask[32];
  20.  
  21. extern struct Env adfEnv;
  22.  
  23. /*
  24.  * adfUpdateBitmap
  25.  *
  26.  */
  27. RETCODE adfUpdateBitmap(struct Volume *vol)
  28. {
  29.     int i;
  30.     struct bRootBlock root;
  31.  
  32. /*printf("adfUpdateBitmap\n");*/
  33.         
  34.     if (adfReadRootBlock(vol, vol->rootBlock,&root)!=RC_OK)
  35.         return RC_ERROR;
  36.  
  37.     root.bmFlag = BM_INVALID;
  38.     if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
  39.         return RC_ERROR;
  40.  
  41.     for(i=0; i<vol->bitmapSize; i++)
  42.     if (vol->bitmapBlocksChg[i]) {
  43.         if (adfWriteBitmapBlock(vol, vol->bitmapBlocks[i], vol->bitmapTable[i])!=RC_OK)
  44.             return RC_ERROR;
  45.           vol->bitmapBlocksChg[i] = FALSE;
  46.     }
  47.  
  48.     root.bmFlag = BM_VALID;
  49.     adfTime2AmigaTime(adfGiveCurrentTime(),&(root.days),&(root.mins),&(root.ticks));
  50.     if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
  51.         return RC_ERROR;
  52.  
  53.     return RC_OK;
  54. }
  55.  
  56.  
  57. /*
  58.  * adfCountFreeBlocks
  59.  *
  60.  */
  61. long adfCountFreeBlocks(struct Volume* vol)
  62. {
  63.     long freeBlocks;
  64.     int j;
  65.  
  66.     freeBlocks = 0L;
  67.     for(j=vol->firstBlock+2; j<=(vol->lastBlock - vol->firstBlock); j++)
  68.         if ( adfIsBlockFree(vol,j) )
  69.             freeBlocks++;
  70.  
  71.     return freeBlocks;
  72. }
  73.  
  74.  
  75. /*
  76.  * adfReadBitmap
  77.  *
  78.  */
  79. RETCODE adfReadBitmap(struct Volume* vol, long nBlock, struct bRootBlock* root)
  80. {
  81.     long mapSize, nSect;
  82.     long j, i;
  83.     struct bBitmapExtBlock bmExt;
  84.  
  85.     mapSize = nBlock / (127*32);
  86.     if ( (nBlock%(127*32))!=0 )
  87.         mapSize++;
  88.     vol->bitmapSize = mapSize;
  89.  
  90.     vol->bitmapTable = (struct bBitmapBlock**) malloc(sizeof(struct bBitmapBlock*)*mapSize);
  91.     if (!vol->bitmapTable) { 
  92.         (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapTable");
  93.         return RC_MALLOC;
  94.     }
  95.     vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
  96.     if (!vol->bitmapBlocks) {
  97.         free(vol->bitmapTable);
  98.         (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
  99.         return RC_MALLOC;
  100.     }
  101.     vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
  102.     if (!vol->bitmapBlocksChg) { 
  103.         free(vol->bitmapTable); free(vol->bitmapBlocks);
  104.         (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
  105.         return RC_MALLOC;
  106.     }
  107.     for(i=0; i<mapSize; i++) {
  108.         vol->bitmapBlocksChg[i] = FALSE;
  109.  
  110.         vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
  111.         if (!vol->bitmapTable[i]) {
  112.             free(vol->bitmapBlocksChg); free(vol->bitmapBlocks);
  113.             for(j=0; j<i; j++) 
  114.                 free(vol->bitmapTable[j]);
  115.             free(vol->bitmapTable);
  116.             (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
  117.             return RC_MALLOC;
  118.         }
  119.     }
  120.  
  121.     j=0; i=0;
  122.     /* bitmap pointers in rootblock : 0 <= i <BM_SIZE */
  123.     while(i<BM_SIZE && root->bmPages[i]!=0) {
  124.         vol->bitmapBlocks[j] = nSect = root->bmPages[i];
  125.         if ( !isSectNumValid(vol,nSect) )
  126.             (*adfEnv.wFct)("adfReadBitmap : sector out of range");
  127.  
  128.         if (adfReadBitmapBlock(vol, nSect, vol->bitmapTable[j])!=RC_OK) {
  129.             adfFreeBitmap(vol);
  130.             return RC_ERROR;
  131.         }
  132.         j++; i++;
  133.     }
  134.     nSect = root->bmExt;
  135.     while(nSect!=0) {
  136.         /* bitmap pointers in bitmapExtBlock, j <= mapSize */
  137.         if (adfReadBitmapExtBlock(vol, nSect, &bmExt)!=RC_OK) {
  138.             adfFreeBitmap(vol);
  139.             return RC_ERROR;
  140.         }
  141.         i=0;
  142.         while(i<127 && j<mapSize) {
  143.             nSect = bmExt.bmPages[i];
  144.             if ( !isSectNumValid(vol,nSect) )
  145.                 (*adfEnv.wFct)("adfReadBitmap : sector out of range");
  146.             vol->bitmapBlocks[j] = nSect;
  147.  
  148.             if (adfReadBitmapBlock(vol, nSect, vol->bitmapTable[j])!=RC_OK) {
  149.                 adfFreeBitmap(vol);
  150.                 return RC_ERROR;
  151.             }
  152.             i++; j++;
  153.         }
  154.         nSect = bmExt.nextBlock;
  155.     }
  156.  
  157.     return RC_OK;
  158. }
  159.  
  160.  
  161. /*
  162.  * adfIsBlockFree
  163.  *
  164.  */
  165. BOOL adfIsBlockFree(struct Volume* vol, SECTNUM nSect)
  166. {
  167.     int sectOfMap = nSect-2;
  168.     int block = sectOfMap/(127*32);
  169.     int indexInMap = (sectOfMap/32)%127;
  170.     
  171. /*printf("sect=%d block=%d ind=%d,  ",sectOfMap,block,indexInMap);
  172. printf("bit=%d,  ",sectOfMap%32);
  173. printf("bitm=%x,  ",bitMask[ sectOfMap%32]);
  174. printf("res=%x,  ",vol->bitmapTable[ block ]->map[ indexInMap ]
  175.         & bitMask[ sectOfMap%32 ]);
  176. */
  177.     return ( (vol->bitmapTable[ block ]->map[ indexInMap ]
  178.         & bitMask[ sectOfMap%32 ])!=0 );
  179. }
  180.  
  181.  
  182. /*
  183.  * adfSetBlockFree OK
  184.  *
  185.  */
  186. void adfSetBlockFree(struct Volume* vol, SECTNUM nSect)
  187. {
  188.     unsigned long oldValue;
  189.     int sectOfMap = nSect-2;
  190.     int block = sectOfMap/(127*32);
  191.     int indexInMap = (sectOfMap/32)%127;
  192.  
  193. /*printf("sect=%d block=%d ind=%d,  ",sectOfMap,block,indexInMap);
  194. printf("bit=%d,  ",sectOfMap%32);
  195. *printf("bitm=%x,  ",bitMask[ sectOfMap%32]);*/
  196.  
  197.     oldValue = vol->bitmapTable[ block ]->map[ indexInMap ];
  198. /*printf("old=%x,  ",oldValue);*/
  199.     vol->bitmapTable[ block ]->map[ indexInMap ]
  200.         = oldValue | bitMask[ sectOfMap%32 ];
  201. /*printf("new=%x,  ",vol->bitmapTable[ block ]->map[ indexInMap ]);*/
  202.  
  203.     vol->bitmapBlocksChg[ block ] = TRUE;
  204. }
  205.  
  206.  
  207. /*
  208.  * adfSetBlockUsed
  209.  *
  210.  */
  211. void adfSetBlockUsed(struct Volume* vol, SECTNUM nSect)
  212. {
  213.     unsigned long oldValue;
  214.     int sectOfMap = nSect-2;
  215.     int block = sectOfMap/(127*32);
  216.     int indexInMap = (sectOfMap/32)%127;
  217.  
  218.     oldValue = vol->bitmapTable[ block ]->map[ indexInMap ];
  219.  
  220.     vol->bitmapTable[ block ]->map[ indexInMap ]
  221.         = oldValue & (~bitMask[ sectOfMap%32 ]);
  222.     vol->bitmapBlocksChg[ block ] = TRUE;
  223. }
  224.  
  225.  
  226. /*
  227.  * adfGet1FreeBlock
  228.  *
  229.  */
  230. SECTNUM adfGet1FreeBlock(struct Volume *vol) {
  231.     SECTNUM block[1];
  232.     if (!adfGetFreeBlocks(vol,1,block))
  233.         return(-1);
  234.     else
  235.         return(block[0]);
  236. }
  237.  
  238. /*
  239.  * adfGetFreeBlocks
  240.  *
  241.  */
  242. BOOL adfGetFreeBlocks(struct Volume* vol, int nbSect, SECTNUM* sectList)
  243. {
  244.     int i, j;
  245.     BOOL diskFull;
  246.     long block = vol->rootBlock;
  247.  
  248.     i = 0;
  249.     diskFull = FALSE;
  250. //printf("lastblock=%ld\n",vol->lastBlock);
  251.     while( i<nbSect && !diskFull ) {
  252.         if ( adfIsBlockFree(vol, block) ) {
  253.             sectList[i] = block;
  254.             i++;
  255.         }
  256. /*        if ( block==vol->lastBlock )
  257.             block = vol->firstBlock+2;*/
  258.         if ( (block+vol->firstBlock)==vol->lastBlock )
  259.             block = 2;
  260.         else if (block==vol->rootBlock-1)
  261.             diskFull = TRUE;
  262.         else
  263.             block++;
  264.     }
  265.  
  266.     if (!diskFull)
  267.         for(j=0; j<nbSect; j++)
  268.             adfSetBlockUsed( vol, sectList[j] );
  269.  
  270.     return (i==nbSect);
  271. }
  272.  
  273.  
  274. /*
  275.  * adfCreateBitmap
  276.  *
  277.  * create bitmap structure in vol
  278.  */
  279. RETCODE adfCreateBitmap(struct Volume *vol)
  280. {
  281.     long nBlock, mapSize ;
  282.     int i, j;
  283.  
  284.     nBlock = vol->lastBlock - vol->firstBlock +1 - 2;
  285.  
  286.     mapSize = nBlock / (127*32);
  287.     if ( (nBlock%(127*32))!=0 )
  288.         mapSize++;
  289.     vol->bitmapSize = mapSize;
  290.  
  291.     vol->bitmapTable = (struct bBitmapBlock**)malloc( sizeof(struct bBitmapBlock*)*mapSize );
  292.     if (!vol->bitmapTable) {
  293.         (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapTable");
  294.         return RC_MALLOC;
  295.     }
  296.  
  297.     vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
  298.     if (!vol->bitmapBlocksChg) {
  299.         free(vol->bitmapTable);
  300.         (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocksChg");
  301.         return RC_MALLOC;
  302.     }
  303.  
  304.     vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
  305.     if (!vol->bitmapBlocks) {
  306.         free(vol->bitmapTable); free(vol->bitmapBlocksChg);
  307.         (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocks");
  308.         return RC_MALLOC;
  309.     }
  310.  
  311.     for(i=0; i<mapSize; i++) {
  312.         vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
  313.         if (!vol->bitmapTable[i]) {
  314.             free(vol->bitmapTable); free(vol->bitmapBlocksChg);
  315.             for(j=0; j<i; j++) 
  316.                 free(vol->bitmapTable[j]);
  317.             free(vol->bitmapTable);
  318.             (*adfEnv.eFct)("adfCreateBitmap : malloc");
  319.             return RC_MALLOC;
  320.         }
  321.     }
  322.  
  323.     for(i=vol->firstBlock+2; i<=(vol->lastBlock - vol->firstBlock); i++)
  324.         adfSetBlockFree(vol, i);
  325.  
  326.     return RC_OK;
  327. }
  328.  
  329.  
  330. /*
  331.  * adfWriteNewBitmap
  332.  *
  333.  * write ext blocks and bitmap
  334.  *
  335.  * uses vol->bitmapSize, 
  336.  */
  337. RETCODE adfWriteNewBitmap(struct Volume *vol)
  338. {
  339.     struct bBitmapExtBlock bitme;
  340.     SECTNUM *bitExtBlock;
  341.     int n, i, k;
  342.     int nExtBlock;
  343.     int nBlock;
  344.     SECTNUM *sectList;
  345.     struct bRootBlock root;
  346.  
  347.     sectList=(SECTNUM*)malloc(sizeof(SECTNUM)*vol->bitmapSize);
  348.     if (!sectList) {
  349.         (*adfEnv.eFct)("adfCreateBitmap : sectList");
  350.         return RC_MALLOC;
  351.     }
  352.  
  353.     if (!adfGetFreeBlocks(vol, vol->bitmapSize, sectList)) {
  354.         free(sectList);
  355.         return RC_ERROR;
  356.     }
  357.     
  358.     if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
  359.         free(sectList);
  360.         return RC_ERROR;
  361.     }
  362.     nBlock = 0;
  363.     n = min( vol->bitmapSize, BM_SIZE );
  364.     for(i=0; i<n; i++)
  365.         root.bmPages[i] = vol->bitmapBlocks[i] = sectList[i];
  366.     nBlock = n;
  367.  
  368.     /* for devices with more than 25*127 blocks == hards disks */
  369.     if (vol->bitmapSize>BM_SIZE) {
  370.  
  371.         nExtBlock = (vol->bitmapSize-BM_SIZE)/127;
  372.         if ((vol->bitmapSize-BM_SIZE)%127)
  373.             nExtBlock++;
  374.  
  375.         bitExtBlock=(SECTNUM*)malloc(sizeof(SECTNUM)*nExtBlock);
  376.         if (!bitExtBlock) {
  377.             free(sectList);
  378.             adfEnv.eFct("adfWriteNewBitmap : malloc failed");
  379.             return RC_MALLOC;
  380.         }
  381.  
  382.         if (!adfGetFreeBlocks(vol, nExtBlock, bitExtBlock)) {  
  383.            free(sectList); free(bitExtBlock);
  384.            return RC_MALLOC;
  385.         }
  386.  
  387.         k = 0;
  388.         root.bmExt = bitExtBlock[ k ];
  389.         while( nBlock<vol->bitmapSize ) {
  390.             i=0;
  391.             while( i<127 && nBlock<vol->bitmapSize ) {
  392.                 bitme.bmPages[i] = vol->bitmapBlocks[nBlock] = sectList[i];
  393.                 i++;
  394.                 nBlock++;
  395.             }
  396.             if ( k+1<nExtBlock )
  397.                 bitme.nextBlock = bitExtBlock[ k+1 ];
  398.             else
  399.                 bitme.nextBlock = 0;
  400.             if (adfWriteBitmapExtBlock(vol, bitExtBlock[ k ], &bitme)!=RC_OK) {
  401.                 free(sectList); free(bitExtBlock);
  402.                 return RC_ERROR;
  403.             }
  404.             k++;
  405.         }
  406.         free( bitExtBlock );
  407.  
  408.     }
  409.     free( sectList);
  410.  
  411.     if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
  412.         return RC_ERROR;
  413.     
  414.     return RC_OK;
  415. }
  416.  
  417. /*
  418.  * adfReadBitmapBlock
  419.  *
  420.  * ENDIAN DEPENDENT
  421.  */
  422. RETCODE
  423. adfReadBitmapBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapBlock* bitm)
  424. {
  425.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  426.  
  427. //printf("bitmap %ld\n",nSect);
  428.     if (adfReadBlock(vol, nSect, buf)!=RC_OK)
  429.         return RC_ERROR;
  430.  
  431.     memcpy(bitm, buf, LOGICAL_BLOCK_SIZE);
  432. #ifdef LITT_ENDIAN
  433.     /* big to little = 68000 to x86 */
  434.     swapEndian((unsigned char*)bitm, SWBL_BITMAP);
  435. #endif
  436.  
  437.     if (bitm->checkSum!=adfNormalSum(buf,0,LOGICAL_BLOCK_SIZE))
  438.         (*adfEnv.wFct)("adfReadBitmapBlock : invalid checksum");
  439.  
  440.     return RC_OK;
  441. }
  442.  
  443.  
  444. /*
  445.  * adfWriteBitmapBlock
  446.  *
  447.  * OK
  448.  */
  449. RETCODE
  450. adfWriteBitmapBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapBlock* bitm)
  451. {
  452.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  453.     unsigned long newSum;
  454.     
  455.     memcpy(buf,bitm,LOGICAL_BLOCK_SIZE);
  456. #ifdef LITT_ENDIAN
  457.     /* little to big */
  458.     swapEndian(buf, SWBL_BITMAP);
  459. #endif
  460.  
  461.     newSum = adfNormalSum(buf, 0, LOGICAL_BLOCK_SIZE);
  462.     swLong(buf,newSum);
  463.  
  464. /*    dumpBlock((unsigned char*)buf);*/
  465.     if (adfWriteBlock(vol, nSect, (unsigned char*)buf)!=RC_OK)
  466.         return RC_ERROR;
  467.  
  468.     return RC_OK;
  469. }
  470.  
  471.  
  472. /*
  473.  * adfReadBitmapExtBlock
  474.  *
  475.  * ENDIAN DEPENDENT
  476.  */
  477. RETCODE
  478. adfReadBitmapExtBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapExtBlock* bitme)
  479. {
  480.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  481.  
  482.     if (adfReadBlock(vol, nSect, buf)!=RC_OK)
  483.         return RC_ERROR;
  484.  
  485.     memcpy(bitme, buf, LOGICAL_BLOCK_SIZE);
  486. #ifdef LITT_ENDIAN
  487.     swapEndian((unsigned char*)bitme, SWBL_BITMAP);
  488. #endif
  489.  
  490.     return RC_OK;
  491. }
  492.  
  493.  
  494. /*
  495.  * adfWriteBitmapExtBlock
  496.  *
  497.  */
  498. RETCODE
  499. adfWriteBitmapExtBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapExtBlock* bitme)
  500. {
  501.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  502.     
  503.     memcpy(buf,bitme, LOGICAL_BLOCK_SIZE);
  504. #ifdef LITT_ENDIAN
  505.     /* little to big */
  506.     swapEndian(buf, SWBL_BITMAPE);
  507. #endif
  508.  
  509. /*    dumpBlock((unsigned char*)buf);*/
  510.     if (adfWriteBlock(vol, nSect, (unsigned char*)buf)!=RC_OK)
  511.         return RC_ERROR;
  512.  
  513.     return RC_OK;
  514. }
  515.  
  516.  
  517. /*
  518.  * adfFreeBitmap
  519.  *
  520.  */
  521. void adfFreeBitmap(struct Volume* vol)
  522. {
  523.     int i;
  524.  
  525.     for(i=0; i<vol->bitmapSize; i++)
  526.         free(vol->bitmapTable[i]);
  527.     vol->bitmapSize = 0;
  528.  
  529.     free(vol->bitmapTable);
  530.     vol->bitmapTable = 0;
  531.  
  532.     free(vol->bitmapBlocks);
  533.     vol->bitmapBlocks = 0;
  534.  
  535.     free(vol->bitmapBlocksChg);
  536.     vol->bitmapBlocksChg = 0;
  537. }
  538.  
  539.  
  540. /*#######################################################################################*/
  541.